%     FASTENER DOCTOR - программа для лечения и конвертации крепежа
%     Copyright (C) 2018  Михаил Козлов
%     Сайт проекта: <http://www.fastenerdoctor.ru/>
%     Адрес электронной почты для связи с разработчиком:
%     <doctor.fastener@gmail.com>
% 
%     Эта программа является свободным программным обеспечением: Вы можете
%     распространять ее и/или изменять, соблюдая условия Универсальной общественной
%     лицензии GNU, опубликованной Фондом свободного программного обеспечения,
%     либо редакции 3, либо (на Ваше усмотрение) любой редакции, выпущенной позже.
% 
%     Эта программа распространяется в надежде на то, что она окажется полезной,
%     но БЕЗ КАКИХ-ЛИБО ГАРАНТИЙ, включая даже подразумеваемую гарантию ТОВАРНОЙ ПРИГОДНОСТИ,
%     либо ПРИГОДНОСТИ ДЛЯ ОПРЕДЕЛЕННЫХ ЦЕЛЕЙ. Ознакомьтесь с Универсальной общественной
%     лицензией GNU для получения более подробной информации.
% 
%     Вы должны были получить копию Универсальной общественной лицензии GNU
%     вместе с этой программой. Если Вы ее не получили, то перейдите по адресу:
%     <http://www.gnu.org/licenses/>.
% 
%     This program is free software: you can redistribute it and/or modify
%     it under the terms of the GNU General Public License as published by
%     the Free Software Foundation, either version 3 of the License, or
%     (at your option) any later version.
% 
%     This program is distributed in the hope that it will be useful,
%     but WITHOUT ANY WARRANTY; without even the implied warranty of
%     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
%     GNU General Public License for more details.
% 
%     You should have received a copy of the GNU General Public License
%     along with this program.  If not, see <https://www.gnu.org/licenses/>.

function Task_Repair_RutFast(RutFast_Repair_Offsets, RutFast_Repair_2D_Holes, RutFast_Repair_3D_Holes, RutFast_Repair_Bush, RutFast_Repair_Coord, RutFast_Repair_RBAR_DOFs, RutFast_Axial_Constraint)

global ErrCode;

global DB_FASTENERS;

if (size(DB_FASTENERS,1) == 0)
    fprintf (1, 'Пустая база данных крепежа!\n');
    ErrCode = -1;
    return;
end

% Инициализация счетчиков

Moved_2D_Hole_Center_Node_Counter = 0;
Moved_3D_Hole_Center_Node_Counter = 0;
Max_2D_Hole_Displacement = 0;
Max_3D_Hole_Displacement = 0;

Repaired_Offsets_Counter = 0;
Removed_Offsets_Counter = 0;
Repaired_Offset_MPC_Counter = 0;
Created_Offset_MPC_Counter = 0;

Repaired_Bush_Connectivity_Counter = 0;
Repaired_Node_An_Coord_Counter = 0;
Repaired_Node_Ref_Coord_Counter = 0;
Deleted_Redundant_CBUSH_Counter = 0;
Repaired_Bush_Stiffness_Counter = 0;
Modified_Axial_Constraint_Counter = 0;
Repaired_RBAR_DOFs_Counter = 0;

Fastener_Repair_Flags = zeros(size(DB_FASTENERS,1),1);

fprintf (1, '    Ход выполнения:\n');

% --- Перемещение центрального узла MPC или bar-паука вдоль оси болта в центр 2D отверстия ---

switch RutFast_Repair_2D_Holes
    
    case 'TRUE'
        
        fprintf (1, '        Починка центральных узлов 2D отверстий...     ');
        
        % Цикл по всем болтам
        for i=1:size(DB_FASTENERS,1)
            
            % Если болт Рутмана
            if (strcmp(DB_FASTENERS{i}.topology, 'rutman_fastener'))
            
                % Исправление центральных узлов 2D отверстий
                [temp_counter_1, temp_counter_2] = Repair_RutFast_2D_Holes(i);
                
                if (ErrCode < 0)
                    return;
                end
                
                % Обновление счетчиков
                Moved_2D_Hole_Center_Node_Counter = Moved_2D_Hole_Center_Node_Counter + temp_counter_1;
                
                if (temp_counter_2 > Max_2D_Hole_Displacement)
                    Max_2D_Hole_Displacement = temp_counter_2;
                end
                
                if (temp_counter_1 > 0)
                    Fastener_Repair_Flags(i) = 1;
                end
            
            end
            
        end
        
        fprintf (1, 'OK!\n');
        
    case 'FALSE'
        % Ничего не делаем
        
    otherwise
        fprintf (1, 'Недопустимое значение параметра RutFast_Repair_2D_Holes !\n');
        ErrCode = -1;
        return;
        
end

% --- Перемещение центрального узла MPC или bar-паука вдоль оси болта в центр 3D отверстия ---

switch RutFast_Repair_3D_Holes
    
    case 'TRUE'
        
        fprintf (1, '        Починка центральных узлов 3D отверстий...     ');
        
        % Цикл по всем болтам
        for i=1:size(DB_FASTENERS,1)
            
            % Если болт Рутмана
            if (strcmp(DB_FASTENERS{i}.topology, 'rutman_fastener'))
            
                % Исправление центральных узлов 3D отверстий
                [temp_counter_1, temp_counter_2] = Repair_RutFast_3D_Holes(i);
                
                if (ErrCode < 0)
                    return;
                end
                
                % Обновление счетчиков
                Moved_3D_Hole_Center_Node_Counter = Moved_3D_Hole_Center_Node_Counter + temp_counter_1;
                
                if (temp_counter_2 > Max_3D_Hole_Displacement)
                    Max_3D_Hole_Displacement = temp_counter_2;
                end
                
                if (temp_counter_1 > 0)
                    Fastener_Repair_Flags(i) = 1;
                end
            
            end
            
        end
        
        fprintf (1, 'OK!\n');
        
    case 'FALSE'
        % Ничего не делаем
        
    otherwise
        fprintf (1, 'Недопустимое значение параметра RutFast_Repair_3D_Holes !\n');
        ErrCode = -1;
        return;
        
end

% --- Починка/удаление офсетов точек смятия ---

switch RutFast_Repair_Offsets
    
    case 'TRUE'
        
        fprintf (1, '        Починка офсетов точек смятия...               ');
        
        % Цикл по всем болтам
        for i=1:size(DB_FASTENERS,1)
            
            % Если болт Рутмана
            if (strcmp(DB_FASTENERS{i}.topology, 'rutman_fastener'))
                
                % Исправление офсетов точек смятия
                [temp_counter_1, temp_counter_2, temp_counter_3] = Repair_RutFast_Offsets(i);
                
                if (ErrCode < 0)
                    return;
                end
                
                % Обновление счетчиков
                Repaired_Offset_MPC_Counter = Repaired_Offset_MPC_Counter + temp_counter_1;
                Created_Offset_MPC_Counter = Created_Offset_MPC_Counter + temp_counter_2;
                Repaired_Offsets_Counter = Repaired_Offsets_Counter + temp_counter_3;
                
                if ((temp_counter_1 > 0) || (temp_counter_2 > 0) || (temp_counter_3 > 0))
                    Fastener_Repair_Flags(i) = 1;
                end
                
            end
            
        end
        
        fprintf (1, 'OK!\n');
        
    case 'REMOVE'
        
        fprintf (1, '        Удаление офсетов точек смятия...              ');
        
        % Цикл по всем болтам
        for i=1:size(DB_FASTENERS,1)
            
            % Если болт Рутмана
            if (strcmp(DB_FASTENERS{i}.topology, 'rutman_fastener'))
                
                % Удаление офсетов точек смятия
                temp_counter_1 = Remove_RutFast_Offsets(i);
                
                if (ErrCode < 0)
                    return;
                end
                
                % Обновление счетчиков
                Removed_Offsets_Counter = Removed_Offsets_Counter + temp_counter_1;
                
                if (temp_counter_1 > 0)
                    Fastener_Repair_Flags(i) = 1;
                end
                
            end
            
        end
        
        fprintf (1, 'OK!\n');
        
    case 'FALSE'
        % Ничего не делаем
        
    otherwise
        fprintf (1, 'Недопустимое значение параметра RutFast_Repair_Offsets !\n');
        ErrCode = -1;
        return;
        
end

% --- Починка систем координат в узлах болта ---

switch RutFast_Repair_Coord
    
    case 'TRUE'
        
        fprintf (1, '        Починка систем координат в узлах болтов...    ');
        
        % Цикл по всем болтам
        for i=1:size(DB_FASTENERS,1)
            
            % Если болт Рутмана
            if (strcmp(DB_FASTENERS{i}.topology, 'rutman_fastener'))
                
                % Исправление систем координат в болте
                [temp_counter_1, temp_counter_2] = Repair_RutFast_Coord(i);
                
                if (ErrCode < 0)
                    return;
                end
                
                % Обновление счетчиков
                Repaired_Node_An_Coord_Counter = Repaired_Node_An_Coord_Counter + temp_counter_1;
                Repaired_Node_Ref_Coord_Counter = Repaired_Node_Ref_Coord_Counter + temp_counter_2;
                
                if ((temp_counter_1 > 0) || (temp_counter_2 > 0))
                    Fastener_Repair_Flags(i) = 1;
                end
            
            end
            
        end
        
        fprintf (1, 'OK!\n');
        
    case 'FALSE'
        % Ничего не делаем
        
    otherwise
        fprintf (1, 'Недопустимое значение параметра RutFast_Repair_Coord !\n');
        ErrCode = -1;
        return;
        
end

% --- Починка ориентации и жесткостей BUSH-элементов ---

switch RutFast_Repair_Bush
    
    case 'TRUE'
        
        fprintf (1, '        Починка BUSH-элементов...                     ');
        
        % Цикл по всем болтам
        for i=1:size(DB_FASTENERS,1)
            
            % Если болт Рутмана
            if (strcmp(DB_FASTENERS{i}.topology, 'rutman_fastener'))
                
                % Исправление BUSH-элементов
                [temp_counter_1, temp_counter_2, temp_counter_3, temp_counter_4, temp_counter_5] = Repair_RutFast_Bush(i);
                
                if (ErrCode < 0)
                    return;
                end
                
                % Обновление счетчиков
                Repaired_Node_An_Coord_Counter = Repaired_Node_An_Coord_Counter + temp_counter_1;
                Repaired_Node_Ref_Coord_Counter = Repaired_Node_Ref_Coord_Counter + temp_counter_2;
                Repaired_Bush_Connectivity_Counter = Repaired_Bush_Connectivity_Counter + temp_counter_3;
                Deleted_Redundant_CBUSH_Counter = Deleted_Redundant_CBUSH_Counter + temp_counter_4;
                Repaired_Bush_Stiffness_Counter = Repaired_Bush_Stiffness_Counter + temp_counter_5;
                
                if ((temp_counter_1 > 0) || (temp_counter_2 > 0) || (temp_counter_3 > 0) || (temp_counter_4 > 0) || (temp_counter_5 > 0))
                    Fastener_Repair_Flags(i) = 1;
                end
            
            end
            
        end
        
        fprintf (1, 'OK!\n');
        
    case 'FALSE'
        % Ничего не делаем
        
    otherwise
        fprintf (1, 'Недопустимое значение параметра RutFast_Repair_Bush !\n');
        ErrCode = -1;
        return;
        
end

% --- Починка/модификация степеней свободы RBAR ---

switch RutFast_Repair_RBAR_DOFs
    
    case 'TRUE'
        
        fprintf (1, '        Починка/модификация степеней свободы RBAR...  ');
        
        % Цикл по всем болтам
        for i=1:size(DB_FASTENERS,1)
            
            % Если болт Рутмана
            if (strcmp(DB_FASTENERS{i}.topology, 'rutman_fastener'))
                
                % Исправление систем координат в болте
                [temp_counter_1, temp_counter_2, temp_counter_3, temp_counter_4] = Repair_RutFast_RBAR_DOFs(i, RutFast_Axial_Constraint);
                
                if (ErrCode < 0)
                    return;
                end
                
                % Обновление счетчиков
                Repaired_Node_An_Coord_Counter = Repaired_Node_An_Coord_Counter + temp_counter_1;
                Repaired_Node_Ref_Coord_Counter = Repaired_Node_Ref_Coord_Counter + temp_counter_2;
                Modified_Axial_Constraint_Counter = Modified_Axial_Constraint_Counter + temp_counter_3;
                Repaired_RBAR_DOFs_Counter = Repaired_RBAR_DOFs_Counter + temp_counter_4;
                
                if ((temp_counter_1 > 0) || (temp_counter_2 > 0) || (temp_counter_3 > 0) || (temp_counter_4 > 0))
                    Fastener_Repair_Flags(i) = 1;
                end
            
            end
            
        end
        
        fprintf (1, 'OK!\n');
        
    case 'FALSE'
        % Ничего не делаем
        
    otherwise
        fprintf (1, 'Недопустимое значение параметра RutFast_Repair_RBAR_DOFs !\n');
        ErrCode = -1;
        return;
        
end

% --- Вывод статистики ---

fprintf (1, '\n    Статистика:\n');

% Общий счетчик исправленных болтов
fprintf (1, '                  Всего исправлено болтов Рутмана: %i\n', sum(Fastener_Repair_Flags));

% Счетчики починки центральных узлов 2D отверстий
if (strcmp(RutFast_Repair_2D_Holes, 'TRUE'))
    fprintf (1, '        Исправлено центральных узлов 2D отверстий: %i', Moved_2D_Hole_Center_Node_Counter);
    if (Moved_2D_Hole_Center_Node_Counter > 0)
        fprintf (1, ', максимальная коррекция: %f\n', Max_2D_Hole_Displacement);
    else
        fprintf (1, '\n');
    end
end

% Счетчики починки центральных узлов 3D отверстий
if (strcmp(RutFast_Repair_3D_Holes, 'TRUE'))
    fprintf (1, '        Исправлено центральных узлов 3D отверстий: %i', Moved_3D_Hole_Center_Node_Counter);
    if (Moved_3D_Hole_Center_Node_Counter > 0)
        fprintf (1, ', максимальная коррекция: %f\n', Max_3D_Hole_Displacement);
    else
        fprintf (1, '\n');
    end
end

% Счетчики починки офсетов точек смятия
if (strcmp(RutFast_Repair_Offsets, 'TRUE'))
    if (Repaired_Offset_MPC_Counter > 0)
        fprintf (1, '                       Исправлено MPC для офсетов: %i\n', Repaired_Offset_MPC_Counter);
    end
    fprintf (1, '                          Создано MPC для офсетов: %i\n', Created_Offset_MPC_Counter);
    fprintf (1, '                  Исправлено офсетов точек смятия: %i\n', Repaired_Offsets_Counter);
end

if (strcmp(RutFast_Repair_Offsets, 'REMOVE'))
    fprintf (1, '                     Удалено офсетов точек смятия: %i\n', Removed_Offsets_Counter);
end

% Счетчики починки систем координат в узлах болтов
if ((Repaired_Node_An_Coord_Counter > 0) || strcmp(RutFast_Repair_Coord, 'TRUE'))
    fprintf (1, '             Исправлено СК анализа в узлах болтов: %i\n', Repaired_Node_An_Coord_Counter);
end
if ((Repaired_Node_Ref_Coord_Counter > 0) || strcmp(RutFast_Repair_Coord, 'TRUE'))
    fprintf (1, '         Исправлено референсных СК в узлах болтов: %i\n', Repaired_Node_Ref_Coord_Counter);
end

% Счетчики починки BUSH-элементов
if (strcmp(RutFast_Repair_Bush, 'TRUE'))
    if (Repaired_Bush_Connectivity_Counter > 0)
        fprintf (1, '        Исправлено BUSH-элементов (порядок узлов): %i\n', Repaired_Bush_Connectivity_Counter);
    end
    if (Deleted_Redundant_CBUSH_Counter > 0)
        fprintf (1, '                    Удалено лишних BUSH-элементов: %i\n', Deleted_Redundant_CBUSH_Counter);
    end
    fprintf (1, '             Исправлено жесткостей BUSH-элементов: %i\n', Repaired_Bush_Stiffness_Counter);
end

% Счетчики починки/модификации степеней свободы RBAR
if (strcmp(RutFast_Repair_RBAR_DOFs, 'TRUE'))
    fprintf (1, '        Изменено RBAR (вращение болта вокруг оси): %i\n', Modified_Axial_Constraint_Counter);
    fprintf (1, ' Исправлено RBAR (починка других степени свободы): %i\n', Repaired_RBAR_DOFs_Counter);
end
